package auth

import (
	"context"
	"encoding/json"
	"regexp"
	"strconv"
	"time"

	"portal/internal/common"
	"portal/internal/errorx"
	"portal/internal/svc"
	"portal/internal/types"
	"portal/model"
	"portal/tools/encryption"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/redis"
)

type CommonLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	rds *redis.Redis
	userModel model.SysUserModel
	roleModel model.SysRoleModel
}


func NewCommonLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CommonLoginLogic {
	rds, err := redis.NewRedis(redis.RedisConf{
		Host: svcCtx.Config.Redis.Host,
		Pass: svcCtx.Config.Redis.Pass,
		Type: svcCtx.Config.Redis.Type,
	})
	if err != nil {
		logx.Errorf("redis init error: %v", err)
	}
	return &CommonLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		rds: rds,
		svcCtx: svcCtx,
		userModel: model.NewSysUserModel(svcCtx.Orm),
		roleModel: model.NewSysRoleModel(svcCtx.Orm),
	}
}

func (l *CommonLoginLogic) CommonLogin(req *types.LoginRequest) (resp *types.CommonResponse, err error) {
	// todo: add your logic here and delete this line
	// 校验入参
	isUname := regexp.MustCompile(common.UserFormat).Match([]byte(req.Username))
	isPword := regexp.MustCompile(common.PasswordFormat).Match([]byte(req.Password))
	if !isUname || !isPword {
		return nil,errorx.NewBizError(500,"账号密码格式不正确")
	}
	account,err := l.userModel.SelectOneByUname(l.ctx,nil,req.Username)
	if err != nil {
		return nil,errorx.NewBizError(500,err.Error())
	}
	if account.DelFlag == common.DELETED_FLAG {
		return nil,errorx.UserUnexistError
	}
	if account.Password != encryption.EncryNoTimeSha256(req.Password,l.svcCtx.Config.JwtSecret) {
		return nil,errorx.NewBizError(500,"账号密码不正确")
	}
	nowTime := time.Now().String()
	token := encryption.EncryptionSha256(account.UserName,l.svcCtx.Config.JwtSecret,nowTime)
	// 登录需要清除之前的登录信息
	pretoken,err := l.rds.GetCtx(l.ctx,common.AuthUserHeader + strconv.Itoa(int(account.UserId)))
	if err == nil {
		l.rds.DelCtx(l.ctx,common.AuthorizationHeader + pretoken)
	}
	l.rds.SetCtx(l.ctx,common.AuthUserHeader + strconv.Itoa(int(account.UserId)),string(token))

	account.Password = ""
	user := &types.User{
		UserId: account.UserId,
	}
	byteAcc,err := json.Marshal(user)
	if err != nil {
		return nil,err
	}
	l.rds.SetexCtx(l.ctx,common.AuthorizationHeader + token,string(byteAcc),common.ExpireTime)
	// l.rds.ExpireCtx(l.ctx,common.AuthorizationHeader + token,common.ExpireTime)
	return &types.CommonResponse{
		Status: 200,
		Msg: "登录成功",
		Data: token,
	},nil
}
